#include "storage/page/page_guard.h"
#include "buffer/buffer_pool_manager.h"

namespace bustub {

BasicPageGuard::BasicPageGuard(BasicPageGuard &&that) noexcept {
  // std::cout << "basic()" << std::endl;
  this->is_dirty_ = that.is_dirty_;
  this->bpm_ = that.bpm_;
  this->page_ = that.page_;
  that.bpm_ = nullptr;
  that.page_ = nullptr;
}

void BasicPageGuard::Drop() {
  // std::cout << " Drop from BasicPageGuard" << std::endl;
  if (bpm_ == nullptr) {
    return;
  }
  bpm_->UnpinPage(page_->GetPageId(), is_dirty_);
  bpm_ = nullptr;
  page_ = nullptr;
}

auto BasicPageGuard::operator=(BasicPageGuard &&that) noexcept -> BasicPageGuard & {
  // std::cout << "basic=" << std::endl;
  if (this->bpm_ != nullptr) {
    this->Drop();
  }
  this->is_dirty_ = that.is_dirty_;
  this->bpm_ = that.bpm_;
  this->page_ = that.page_;
  that.bpm_ = nullptr;
  that.page_ = nullptr;
  return *this;
}

BasicPageGuard::~BasicPageGuard() {
  if (bpm_ != nullptr) {
    this->Drop();
  }
};  // NOLINT

ReadPageGuard::ReadPageGuard(ReadPageGuard &&that) noexcept : guard_(std::move(that.guard_)) {
  // std::cout << "read()=" << std::endl;
}

auto ReadPageGuard::operator=(ReadPageGuard &&that) noexcept -> ReadPageGuard & {
  // std::cout << "read=" << std::endl;
  this->Drop();
  this->guard_ = std::move(that.guard_);
  return *this;
}

void ReadPageGuard::Drop() {
  // std::cout << "read drop" << std::endl;
  if (guard_.bpm_ == nullptr) {
    return;
  }
  guard_.page_->RUnlatch();
  guard_.Drop();
}

ReadPageGuard::~ReadPageGuard() {
  // std::cout << "read destroy" << std::endl;
  this->Drop();
}  // NOLINT

WritePageGuard::WritePageGuard(WritePageGuard &&that) noexcept : guard_(std::move(that.guard_)) {
  // std::cout << "write()" << std::endl;
}
auto WritePageGuard::operator=(WritePageGuard &&that) noexcept -> WritePageGuard & {
  // std::cout << "write=" << std::endl;
  this->Drop();
  this->guard_ = std::move(that.guard_);
  return *this;
}

void WritePageGuard::Drop() {
  // std::cout << "write drop" << std::endl;
  if (guard_.bpm_ == nullptr) {
    return;
  }
  guard_.page_->WUnlatch();
  guard_.Drop();
}

WritePageGuard::~WritePageGuard() {
  // std::cout << "write destroy" << std::endl;
  this->Drop();
}  // NOLINT

}  // namespace bustub
